

public class TVertice {
	private Comparable etiqueta;
	private TLista adyacentes;
	private boolean visitado;

	public Comparable getEtiqueta() {
		return etiqueta;
	}

	public TLista getAdyacentes() {
		return adyacentes;
	}

	public TVertice (Comparable unaEtiqueta) {
		etiqueta = unaEtiqueta;
		adyacentes = new TLista();
	}	public boolean getVisitado()
	{
		return visitado;
	}
	
	public void setVisitado(boolean valor)
	{
		this.visitado = valor;
	}
	
	public TAdyacencia buscarAdyacencia(TVertice verticeDestino) {
		if (verticeDestino != null) {
			TElemento elem = adyacentes.buscar(verticeDestino.getEtiqueta());
			if (elem != null) {
				return (TAdyacencia) elem.getDatos();
			}
		}
		return null;
	}
	
	public Integer obtenerCostoAdyacencia(TVertice verticeDestino) {
		TAdyacencia ady = buscarAdyacencia(verticeDestino);
		if (ady != null) {
			return (Integer)ady.getCosto();
		}
		return -1;
	}
	
	public boolean insertarAdyacencia(Comparable costo, TVertice verticeDestino) {
		if (buscarAdyacencia(verticeDestino) == null) {
			TAdyacencia ady = new TAdyacencia(costo, verticeDestino);
			TElemento elem = new TElemento(verticeDestino.getEtiqueta(), ady);
			return adyacentes.insertarAlFinal(elem);
		}
		return false;
	}

	public boolean eliminarAdyacencia(Comparable nomVerticeDestino) {
		return adyacentes.eliminar(nomVerticeDestino) != null;
	}
	/**
	 * Metodo que realiza un bpf a partir de un vertice
	 * @param recorrido
	 */
	public void bpf(TRecorrido recorrido)
	{
		visitar();		
		recorrido.insertarAlFinal(new TElemento(this.etiqueta,this));
		TVertice vertice = this.primerAdyacente();				
		while(vertice!=null)
		{
			if(!vertice.visitado)
				vertice.bpf(recorrido);
			vertice = this.siguienteAdyacente(vertice);
		}
	}
	public void visitar()
	{
		visitado = true;
	}
	/**
	 * Metodo que devuelve el primer adyacente al vertice
	 * @return primero
	 */
	public TVertice primerAdyacente()
	{
		if (!this.adyacentes.esVacia())
			return (TVertice) (((TAdyacencia)this.adyacentes.obtenerPrimero().getDatos()).getDestino());
		return null;
	}
	
	/**
	 * Metodo que devuelve el proximo adyacente, dado un adyacente al vertice
	 * @param anterior
	 * @return siguiente
	 */
	public TVertice siguienteAdyacente(TVertice anterior)
	{
		if (anterior != null)
		{
			TElemento elemento = this.adyacentes.buscar(anterior.etiqueta);
			if (elemento != null)
			{
				elemento = elemento.getSiguiente();
				if (elemento != null)
					return (TVertice) (((TAdyacencia)elemento.getDatos()).getDestino());
			}
		}
		return null;
	}
	/**
	 * Metodo que a partir de un vertice origen obtiene todos los caminos a un vertice destino.
	 * @param destino
	 * @param elCamino
	 * @param caminos
	 * @return todosLosCaminos
	 */
	public TCaminos obtenerTodosLosCaminos(TVertice destino, TCamino elCamino , TCaminos caminos)
	{
		visitar();
		TVertice primero = this.primerAdyacente();
		while (primero != null)
		{
			if(!primero.visitado)
			{
				elCamino.insertarAlFinal(new TElemento(primero.getEtiqueta(),primero));
				if( primero.getEtiqueta().compareTo(destino.getEtiqueta()) == 0)
				{
					caminos.agregarCamino(elCamino);
					elCamino.eliminar(primero.getEtiqueta());
					primero.visitado = false;
				}
				else
				{
					primero.obtenerTodosLosCaminos(destino, elCamino, caminos);
				}
			}
			primero = this.siguienteAdyacente(primero);
		}
		elCamino.eliminar(this.etiqueta);
		this.visitado = false;
		return caminos;
	}
	
}
